package com.yupi.springbootinit.statemachine.example;

import com.yupi.springbootinit.statemachine.annotation.RequireDepartment;
import com.yupi.springbootinit.statemachine.annotation.StateTransitionPermission;
import com.yupi.springbootinit.statemachine.core.StateContext;
import com.yupi.springbootinit.statemachine.core.TransitionResult;
import com.yupi.springbootinit.statemachine.permission.PermissionManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 权限验证注解使用示例
 * 展示如何在业务方法中使用权限验证注解
 */
@Slf4j
@Service
public class PermissionAnnotationExample {
    
    @Autowired
    private PermissionManager permissionManager;
    
    /**
     * 示例1：使用StateTransitionPermission注解验证状态转换权限
     * 适用于状态机的状态转换方法
     */
    @StateTransitionPermission(
        entityType = "ORDER",
        message = "您没有权限执行订单状态转换",
        logPermissionCheck = true
    )
    public TransitionResult executeOrderStateTransition(StateContext context) {
        log.info("执行订单状态转换: {} -> {}", 
            context.getCurrentState().getCode(), 
            context.getTargetState().getCode());
        
        // 实际的状态转换业务逻辑
        // ...
        
        return TransitionResult.success(null, null, null, System.currentTimeMillis());
    }
    
    /**
     * 示例2：使用StateTransitionPermission注解with自定义条件
     * 使用SpEL表达式进行复杂的权限验证
     */
    @StateTransitionPermission(
        entityType = "PROCESS_INSTANCE",
        condition = "#permissionManager.validateStateTransition(#context) and #context.operatorId != null",
        message = "工序状态转换权限验证失败"
    )
    public TransitionResult executeProcessStateTransition(StateContext context) {
        log.info("执行工序状态转换: 实体[{}] {} -> {}", 
            context.getEntityId(),
            context.getCurrentState().getCode(), 
            context.getTargetState().getCode());
        
        // 工序状态转换业务逻辑
        // ...
        
        return TransitionResult.success(null, null, null, System.currentTimeMillis());
    }
    
    /**
     * 示例3：使用RequireDepartment注解限制部门访问
     * 只允许项目部和管理员访问
     */
    @RequireDepartment(
        departmentIds = {2},
        departmentNames = {"项目部"},
        allowAdmin = true,
        message = "只有项目部用户才能创建销售订单",
        logAccess = true
    )
    public String createSalesOrder(Long userId, String orderInfo) {
        log.info("用户[{}]创建销售订单: {}", userId, orderInfo);
        
        // 创建销售订单的业务逻辑
        // ...
        
        return "销售订单创建成功";
    }
    
    /**
     * 示例4：使用RequireDepartment注解限制工程部访问
     * 只允许工程部用户创建工艺单
     */
    @RequireDepartment(
        departmentIds = {3},
        departmentNames = {"工程部"},
        message = "只有工程部用户才能创建工艺单"
    )
    public String createProcessSheet(Long userId, String processInfo) {
        log.info("用户[{}]创建工艺单: {}", userId, processInfo);
        
        // 创建工艺单的业务逻辑
        // ...
        
        return "工艺单创建成功";
    }
    
    /**
     * 示例5：使用RequireDepartment注解限制PMC访问
     * 只允许PMC用户创建生产排期
     */
    @RequireDepartment(
        departmentIds = {4},
        departmentNames = {"PMC"},
        message = "只有PMC用户才能创建生产排期"
    )
    public String createProductionSchedule(Long userId, String scheduleInfo) {
        log.info("用户[{}]创建生产排期: {}", userId, scheduleInfo);
        
        // 创建生产排期的业务逻辑
        // ...
        
        return "生产排期创建成功";
    }
    
    /**
     * 示例6：使用RequireDepartment注解限制生产部访问
     * 只允许生产部用户执行工序
     */
    @RequireDepartment(
        departmentIds = {5},
        departmentNames = {"生产部"},
        message = "只有生产部用户才能执行工序操作"
    )
    public String executeProcess(Long userId, Long processId) {
        log.info("用户[{}]执行工序[{}]", userId, processId);
        
        // 执行工序的业务逻辑
        // ...
        
        return "工序执行成功";
    }
    
    /**
     * 示例7：使用RequireDepartment注解限制品质部访问
     * 只允许品质部用户执行质检
     */
    @RequireDepartment(
        departmentIds = {6},
        departmentNames = {"品质部"},
        message = "只有品质部用户才能执行质检操作"
    )
    public String executeQualityInspection(Long userId, Long inspectionId) {
        log.info("用户[{}]执行质检[{}]", userId, inspectionId);
        
        // 执行质检的业务逻辑
        // ...
        
        return "质检执行成功";
    }
    
    /**
     * 示例8：组合使用多个部门权限
     * 允许多个部门访问的方法
     */
    @RequireDepartment(
        departmentIds = {2, 3, 4},
        departmentNames = {"项目部", "工程部", "PMC"},
        message = "只有项目部、工程部或PMC用户才能查看订单详情"
    )
    public String viewOrderDetails(Long userId, Long orderId) {
        log.info("用户[{}]查看订单[{}]详情", userId, orderId);
        
        // 查看订单详情的业务逻辑
        // ...
        
        return "订单详情查看成功";
    }
    
    /**
     * 示例9：不使用注解的方法（所有用户都可以访问）
     * 用于对比展示注解的作用
     */
    public String getSystemInfo(Long userId) {
        log.info("用户[{}]获取系统信息", userId);
        
        // 获取系统信息的业务逻辑
        // ...
        
        return "系统信息获取成功";
    }
    
    /**
     * 示例10：禁用权限验证的方法
     * 使用enabled=false禁用权限验证
     */
    @StateTransitionPermission(
        enabled = false,
        message = "此方法已禁用权限验证"
    )
    public TransitionResult executeWithoutPermissionCheck(StateContext context) {
        log.info("执行无权限验证的状态转换");
        
        // 无权限验证的状态转换逻辑
        // ...
        
        return TransitionResult.success(null, null, null, System.currentTimeMillis());
    }
}